perf(desktop): reduce UI stalls during tool output - #3921
Conversation
Astro-Han
left a comment
There was a problem hiding this comment.
I reviewed this head and found blocking issues.
[P1] Batching caches unbounded raw output before redaction/caps
app-shell-session-events.ts:167-178 enqueues full tool_output_delta into pendingEvents; redaction and size caps only happen in applyToolOutputChunk() at frame time — burst can hold large unredacted data pre-paint → OOM risk.
Fix: redact and bound/coalesce at enqueue, not at paint.
[P2] Delayed frame resurrects cleared session state
Frame callback unconditionally projects pending events; cleanup doesn't drop batch and clear runs separately → delete session then frame creates placeholder turn/tool for deleted ID.
Fix: tie drop/cancel to teardown/delete with regression for delayed-frame-after-clear.
Hosted test/windows_recovery: SUCCESS, but code is NO-GO.
简体中文
批量缓存与清理竞争问题。Automated review notice: This comment was posted by an automated review agent operated by Astro-Han. It is not an independent human review and does not replace one.
|
Follow-up correction in
Verification:
The remaining regressions cover the intended frame publication bound and the delayed-frame-after-clear race. |
e9e0bbc to
e98bbf0
Compare
e98bbf0 to
fcfa981
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
Reviewed at exact head fcfa981eb15d9127e94b486d2e240923d72e77c8. Approving with comments (P2 only).
The delayed-frame-after-clear race is fixed (dropDisplayEvents from clearSessionRendererState). Agreed that a synchronous flush every N events would fight this PR's animation-frame batching, so that path should not come back.
[P2] Putting tool_output_delta through scheduleDisplayEvent still leaves pendingEvents uncapped. Each producer chunk is already bounded, but the renderer list is not: a flood can sit until rAF (or the 100ms timeout) and then apply as one long paint. Please drop-oldest / coalesce in the pending structure (reuse the existing 200-chunk / 16KiB live-turn cap) without extra setState.
CI test on this SHA is green. Not blocking.
Publish high-frequency tool output once per animation frame while preserving synchronous lifecycle ordering.\n\nBound pending output with the existing live-turn limits and discard queued events when a session is cleared.\n\nGenerated-by: Codex
0419549 to
24a025e
Compare
Summary
Live tool output currently publishes every chunk directly to Renderer state. Frequent chunks trigger repeated React updates within one display frame.
This can make the interface feel unresponsive while the model is working. Expanding tool details can lag, and loading animations can drop frames.
tool_output_deltapublishes a separate state update.All output chunks remain ordered and complete. Lifecycle and readiness events remain synchronous and flush pending output before they run. Session teardown discards its queued events so a delayed frame cannot restore cleared state.
No screenshot or recording is included. This problem affects transient frame pacing during live streaming, which static images cannot show reliably.
Verification
npm --workspace @maka/desktop run build:mainnode --test apps/desktop/dist/main/__tests__/streaming-handoff.test.jsgit diff --checkAI use
Select exactly one:
Tool(s) and scope: Codex traced the Renderer event flow, implemented frame batching and the session teardown fix, added regression tests, and ran the listed checks. The affected commits include
Generated-by: Codextrailers.Checklist
Does this PR entail a change in behavior?